package app.server.project.main.service.service.rank;

import app.server.project.main.service.db.dao.user.UserRankDao;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.event.EventListener;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.time.DayOfWeek;
import java.time.Duration;
import java.time.LocalDateTime;

@AllArgsConstructor
@Component
@Slf4j
public class InviteWeekRank extends CommonRank {

    private final UserRankDao userRankDao;

    /**
     * 获取本周三的指定时间
     *
     * @param hour   小时（0-23）
     * @param minute 分钟（0-59）
     * @param second 秒（0-59）
     */
    public LocalDateTime getCurrentWeekWednesday(int hour, int minute, int second) {
        LocalDateTime now = LocalDateTime.now();
        DayOfWeek currentDay = now.getDayOfWeek();

        // 星期三在DayOfWeek中是WEDNESDAY，对应数值3
        int daysToWednesday;
        if (currentDay.getValue() <= DayOfWeek.WEDNESDAY.getValue()) {
            // 当前日期在本周三或之前，计算到本周三的天数
            daysToWednesday = DayOfWeek.WEDNESDAY.getValue() - currentDay.getValue();
        } else {
            // 当前日期在本周三之后，计算回溯到本周三的天数（例如周四需要减1天）
            daysToWednesday = -(currentDay.getValue() - DayOfWeek.WEDNESDAY.getValue());
        }

        // 计算并设置具体时间
        return now.plusDays(daysToWednesday)
                .withHour(hour)
                .withMinute(minute)
                .withSecond(second)
                .withNano(0);
    }

    /**
     * 获取下次星期三的指定时间
     *
     * @param hour   小时（0-23）
     * @param minute 分钟（0-59）
     * @param second 秒（0-59）
     */
    private LocalDateTime getNextWednesday(int hour, int minute, int second) {
        LocalDateTime now = LocalDateTime.now();
        DayOfWeek currentDay = now.getDayOfWeek();

        // 星期三在DayOfWeek中是WEDNESDAY，对应数值3
        int daysToAdd;
        if (currentDay.getValue() < DayOfWeek.WEDNESDAY.getValue()) {
            // 当前时间在星期三之前，计算到本周三的天数
            daysToAdd = DayOfWeek.WEDNESDAY.getValue() - currentDay.getValue();
        } else if (currentDay.getValue() == DayOfWeek.WEDNESDAY.getValue()) {
            // 当前是星期三，判断是否已过目标时间
            LocalDateTime targetToday = now.withHour(hour).withMinute(minute).withSecond(second);
            if (now.isBefore(targetToday)) {
                // 今天还没到目标时间，就是今天
                daysToAdd = 0;
            } else {
                // 已经过了今天的目标时间，取下周的星期三
                daysToAdd = 7;
            }
        } else {
            // 当前时间在星期三之后，计算到下周三的天数
            daysToAdd = 7 - (currentDay.getValue() - DayOfWeek.WEDNESDAY.getValue());
        }

        // 计算并设置具体时间
        return now.plusDays(daysToAdd)
                .withHour(hour)
                .withMinute(minute)
                .withSecond(second)
                .withNano(0);
    }

    @Override
    public void doSettlement() {
        this.userRankDao.reset(this.getRankId());
    }

    @Override
    public long getNextSettlementTime() {

        var now = LocalDateTime.now();
        var tomorrow = getNextWednesday(0, 0, 0);
        log.info("tomorrow: {}", tomorrow);
        var day = Duration.between(now, tomorrow);
        return day.toSeconds();
    }

    @EventListener(ApplicationReadyEvent.class)
    public void initRank() {
        this.init(RankType.InviteWeek);
    }

    @Scheduled(cron = "0 0 0 ? * WED")
    public void cornTime() {
        this.beginSettlement();
    }
}
